<template>
    <div id="GoodListPage">
        <!-- 顶部筛选搜索bar -->
        <div id="topBar">
            <el-input style="flex: 1;margin-right: 1rem;max-width: 30%;;" v-model="searchData.name"
                placeholder="请输入商品名称" clearable></el-input>
            <div id="topBarSell">
                <span>{{ searchData.notsell ? '售罄' : '在售' }}</span>
                <el-switch v-model="searchData.notsell" />
            </div>
            <el-select style="margin-right: 1rem;" v-model="searchData.type_id" placeholder="请选择商品类别">
                <el-option v-for="item in goodsType" :key="item.id" :label="item.name" :value="item.id"></el-option>
            </el-select>
            <el-tooltip effect="dark" placement="bottom" content="搜索">
                <el-button :icon="Search" @click="search(true)" circle />
            </el-tooltip>
            <el-tooltip effect="dark" placement="bottom" content="清空">
                <el-button :icon="Close" @click="cleanCondition" circle />
            </el-tooltip>
        </div>
        <!-- 表格 -->
        <el-table :data="goodsData" style="width: 80%;margin: 0 auto;">
            <el-table-column prop="id" label="id" align="center"></el-table-column>
            <el-table-column label="商品图片" align="center">
                <template #default="scope">
                    <el-image :src="proxy.GLOBAL.OSSImageUrlRoot + 'goodsImage/' + scope.row.id + '.png'" fit="contain"
                        style="height: 80px;"
                        :preview-src-list="[proxy.GLOBAL.OSSImageUrlRoot + 'goodsImage/' + scope.row.id + '.png']">
                        <template #error>
                            <div class="image-slot">
                                <el-icon>
                                    <Picture />
                                </el-icon>
                            </div>
                        </template>
                    </el-image>
                </template>
            </el-table-column>
            <el-table-column prop="name" label="商品名称" align="center"></el-table-column>
            <el-table-column prop="description" label="描述" align="center"></el-table-column>
            <el-table-column prop="price" label="价格" align="center"></el-table-column>
            <el-table-column prop="type_id" label="商品类别id" align="center"></el-table-column>
            <el-table-column prop="notsell" label="状态" align="center">
                <template #default="scope">
                    <span>{{ scope.row.notsell ? '售罄' : '在售' }}</span>
                </template>
            </el-table-column>
            <el-table-column label="操作" fixed="right" align="center">
                <template #default="scope">
                    <el-tooltip effect="dark" placement="bottom" content="编辑">
                        <el-button type="primary" :icon="Edit" circle
                            @click="currentDataChange(scope.row, currentGood); ShowStatus.editGood = true;" />
                    </el-tooltip>
                    <el-tooltip effect="dark" placement="bottom" content="删除">
                        <el-button type="danger" :icon="Delete" circle @click="deleteGood(scope.row.id)" />
                    </el-tooltip>
                </template>
            </el-table-column>
        </el-table>
        <!-- 分页 -->
        <el-pagination style="margin: 2rem auto;justify-content: center;" background layout="prev, pager, next"
            :page-size="pageSize" @current-change="pageCurrentChange"
            :hide-on-single-page="goodsTotal < pageSize ? true : false" :total="goodsTotal" />
        <!-- 添加商品 -->
        <el-button id="addGoods" @click="ShowStatus.addGood = true">添加商品</el-button>
        <!-- 添加商品抽屉 -->
        <el-drawer v-model="ShowStatus.addGood" direction="rtl">
            <template #title>
                <h3>添加商品</h3>
            </template>
            <template #default>
                <el-form ref="addGoodsFormRef" :rules="formRuleAddGoods" :model="addGoodsData" label-position="top">
                    <el-form-item label="商品名称" prop="name">
                        <el-input v-model="addGoodsData.name" placeholder="请输入商品名称" clearable></el-input>
                    </el-form-item>
                    <el-form-item label="商品描述" prop="description">
                        <el-input type="textarea" v-model="addGoodsData.description" placeholder="请输入商品描述" clearable
                            :autosize="{ minRows: 2, maxRows: 4 }"></el-input>
                    </el-form-item>
                    <el-form-item label="商品价格" prop="price">
                        <el-input-number v-model="addGoodsData.price" size="large" :precision="2" :step="1" />
                    </el-form-item>
                    <el-form-item label="商品参数" id="param-form-item">
                        <div v-for="paramsData in addGoodsData.param_data" :key="paramsData.id" class="paramsBar">
                            <el-input v-model="paramsData.group" placeholder="请输入参数名称" class="paramsInput"></el-input>
                            <el-tag v-for="(param, index) in paramsData.params" :key="index"
                                @close="handleTagClose(paramsData.id, index)" class="tag" closable>{{ param }}</el-tag>
                            <el-input v-model="paramsData.inputParams" @blur="addParamInputConfirm(paramsData)"
                                @keyup.enter="addParamInputConfirm(paramsData)" ref="addParamInputRef"
                                v-show="paramsData.addParam" size="small" class="tagInput"></el-input>
                            <el-button v-show="!paramsData.addParam" class="button-new-tag ml-1" size="small"
                                @click="addNewParam(paramsData.id)">添加新参数项</el-button>
                            <el-divider border-style="dashed" />
                        </div>
                        <el-button
                            @click="addGoodsData.param_data.push({ id: GoodsParamsDataId++, 'group': '', params: [], inputParams: '', addParam: false })">添加参数</el-button>
                    </el-form-item>
                    <el-form-item label="商品类别" prop="type_id">
                        <el-select style="margin-right: 1rem;" v-model="addGoodsData.type_id" placeholder="请选择商品类别">
                            <el-option v-for="item in goodsType" :key="item.id" :label="item.name"
                                :value="item.id"></el-option>
                        </el-select>
                    </el-form-item>
                    <el-form-item label="是否售罄" prop="notsell">
                        <span>{{ addGoodsData.notsell ? '售罄' : '在售' }}</span>
                        <el-switch v-model="addGoodsData.notsell" />
                    </el-form-item>
                </el-form>
            </template>
            <template #footer>
                <div style="flex: auto">
                    <el-button @click="ShowStatus.addGood = false">取消</el-button>
                    <el-button type="primary" @click="addGoods(); ShowStatus.addGood = false">提交</el-button>
                </div>
            </template>
        </el-drawer>
        <!-- 编辑对话框 -->
        <el-dialog v-model="ShowStatus.editGood" title="编辑商品">
            <el-form ref="editGoodForm" :model="currentGood" label-position="top" :rules="formRuleEditGoods">
                <el-form-item prop="id">
                    <span>商品id：{{ currentGood.id }}</span>
                </el-form-item>
                <el-form-item label="商品图片" class="editImage">
                    <el-image :src="proxy.GLOBAL.OSSImageUrlRoot + 'goodsImage/' + currentGood.id + '.png'"
                        fit="contain" style="height: 80px;"
                        :preview-src-list="[proxy.GLOBAL.OSSImageUrlRoot + 'goodsImage/' + currentGood.id + '.png']">
                        <template #error>
                            <div class="image-slot">
                                <el-icon>
                                    <Picture />
                                </el-icon>
                            </div>
                        </template>
                    </el-image>
                    <el-upload :headers="imgUploadHeaders" ref="upload" list-type="picture" :action="uploadImageUrl"
                        :limit="1" :on-exceed="handleExceed" :auto-upload="false" accept=".jpg,.png"
                        :on-error="imgUploadError" :on-success="imgUploadSuccess">
                        <template #trigger>
                            <el-button style="margin-right: 1rem;" type="primary">选择文件</el-button>
                        </template>
                        <el-button type="success" @click="submitGoodImage">上传图片</el-button>
                        <el-button type="danger" @click="deleteGoodImage">删除图片</el-button>
                    </el-upload>
                </el-form-item>
                <el-form-item prop="name" label="商品名称">
                    <el-input v-model="currentGood.name" placeholder="请输入商品名称" clear></el-input>
                </el-form-item>
                <el-form-item prop="name" label="商品描述">
                    <el-input type="textarea" v-model="currentGood.description" placeholder="请输入商品描述"
                        :autosize="{ minRows: 2 }" clear></el-input>
                </el-form-item>
                <el-form-item label="商品价格" prop="price">
                    <el-input-number v-model="currentGood.price" size="large" :precision="2" :step="1" />
                </el-form-item>
                <el-form-item label="商品参数" prop="param_data">
                    <div style="padding: 0 1rem;">
                        <div v-for="params in JSON.parse(currentGood.param_data)" :key="params.id">
                            <div style="padding-left: 1rem;">{{ params.group }}</div>
                            <el-tag class="mx-1 paramsTag" size="large" type="info"
                                v-for="(param, index) in params.params" :key="index">{{ param }}</el-tag>
                        </div>
                    </div>
                </el-form-item>
                <el-form-item label="商品类别" prop="type_id">
                    <el-select style="margin-right: 1rem;" v-model="currentGood.type_id" placeholder="请选择商品类别">
                        <el-option v-for="item in goodsType" :key="item.id" :label="item.name"
                            :value="item.id"></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="是否售罄" prop="notsell">
                    <span>{{ currentGood.notsell ? '售罄' : '在售' }}</span>
                    <el-switch :active-value="1" :inactive-value="0" v-model="currentGood.notsell" />
                </el-form-item>
            </el-form>
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="ShowStatus.editGood = false">取消</el-button>
                    <el-button type="primary" @click="submitEditGood(); ShowStatus.editGood = false;">提交</el-button>
                </span>
            </template>
        </el-dialog>
    </div>
</template>

<script setup>
import { Edit, Delete, Search, Close } from '@element-plus/icons-vue';
import { getData, currentDataChange } from '../utils/GeneralTool' // 导入全局工具
import { ref, reactive, onMounted, nextTick, computed, getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance()
import { ElNotification, ElMessageBox } from 'element-plus'
import Cookies from 'js-cookie' // 获取Cookie
import router from '@/router';

// --数据获取--
let goodsData = ref([])
let goodsType = ref([])
let goodsTotal = ref(0)
let currentPage = ref(1) // 表格当前页
let pageSize = ref(10) // 表格页大小
let searchOrNot = ref(false) // 是否搜索过
const getGoodsData = () => { // 获取商品数据
    let params = [currentPage.value, pageSize.value]
    proxy.$api.getAllGoods(params)
        .then(res => {
            getData(res.goodsData, goodsData)
            goodsTotal.value = res.total
        })
}
const getAllType = () => { // 获取商品类型数据
    proxy.$api.getAllType().then(res => {
        getData(res, goodsType)
    })
}
onMounted(() => {
    getGoodsData()
    getAllType()
})
const pageCurrentChange = (val) => {
    currentPage.value = val // 更改当前页
    if (searchOrNot.value) { // 若筛选搜索过就调用筛选搜索方法
        search(false)
        return
    }
    getGoodsData()
}
// --筛选搜索商品--
let searchData = reactive({
    name: null,
    type_id: null,
    notsell: false,
})
let cleanCondition = () => {
    searchData.name = null
    searchData.type_id = null
    searchData.notsell = false
}
const search = (buttonClickOrNot) => {
    if (buttonClickOrNot) {
        currentPage.value = 1 // 重设当前页数和数据总量，进行搜索 
        goodsTotal.value = 0
    }
    searchOrNot.value = true // 修改搜索状态量，已经搜索过了
    if (searchData.name == '') searchData.name = null
    // 搜索数据
    let conditions = [searchData.name, searchData.notsell, searchData.type_id, currentPage.value, pageSize.value]
    proxy.$api.searchGoodByCondition(conditions)
        .then(res => {
            getData(res.goodsData, goodsData)
            goodsTotal.value = res.total
        })
}
// --编辑商品--
let currentGood = reactive({}) // 输入数据载体
let ShowStatus = reactive({ // 对话框显示 / 隐藏状态量
    editGood: false,
    addGood: false,
})
const formRuleEditGoods = reactive({
    name: [{ required: true, message: '请输入商品名称', trigger: 'blur' }],
    description: [{ required: true, message: '请输入商品描述', trigger: 'blur' }],
})
let editGoodForm = ref()
const submitEditGood = async () => { // 提交更新商品
    await editGoodForm.value.validate((valid) => {
        if (valid) {
            proxy.$api.updateGoods(currentGood)
                .then(res => {
                    if (res.affectedRows) {
                        ElNotification({
                            title: '提交成功',
                            type: 'success'
                        })
                        router.go(0)
                    } else {
                        ElNotification({
                            title: '提交失败，存入数据库失败',
                            type: 'error'
                        })
                    }
                })
        } else {
            ElNotification({
                title: '提交失败，请完善商品信息',
                type: 'error'
            })
        }
    })
}
// --添加商品--
let addGoodsData = reactive({
    price: 0,
    param_data: [],
    notsell: false,
})
let GoodsParamsDataId = ref(1) // 商品参数列表的id索引标记量
const addGoodsFormRef = ref() // 添加货物表单对象
const formRuleAddGoods = reactive({ // 添加货物的表单规则
    name: [{ required: true, message: '请输入商品名称', trigger: 'blur' }],
    description: [{ required: true, message: '请输入商品描述', trigger: 'blur' }],
    type_id: [{ required: true, message: '请选择商品类别', trigger: 'change' }],
})
const addParamInputRef = ref()
const addNewParam = (index) => { // 添加商品参数属性事件
    addGoodsData.param_data[index - 1].addParam = true // 显示input框
    nextTick(() => {
        addParamInputRef.value[index - 1].input.focus() // 添加input的聚焦
    })
}
const handleTagClose = (paramsDataId, index) => { // 关闭该商品参数属性事件
    addGoodsData.param_data.forEach(e => {
        if (e.id == paramsDataId) {
            e.params.splice(e.params.indexOf(index), 1) // 去掉该参数属性
        }
    })
}
const addParamInputConfirm = (paramsData) => { // 当参数属性input框取消聚焦或者用户按下回车，若没有输入数据，归为添加新参数按钮事件，若有生成新tag
    let inputValue = addParamInputRef.value[paramsData.id - 1].input.value
    if (inputValue) {
        paramsData.params.push(inputValue)
    }
    paramsData.addParam = false
    addParamInputRef.value[paramsData.id - 1].input.value = '' // 复位
    /* 写到这里！处理input框! */
}
const addGoods = async () => { // 提交添加商品事件
    await addGoodsFormRef.value.validate((valid) => { // 表单检验
        if (valid) { // 表单规则校验通过
            // 检查paramsData内的数据
            let data = []
            addGoodsData.param_data.forEach(e => {
                if (e.group != '' && e.params.length != 0) { // 若有数据
                    const filterArr = ['inputParams', 'addParam']; // 过滤属性数组
                    for (let key in e) { // 先删除'inputParams','addParam'两个无用属性
                        filterArr.find((item) => {
                            if (key == item) {
                                delete e[item]
                            }
                        })
                    }
                    data.push(e) // 加入数组
                }
            })
            let GoodData = {
                name: addGoodsData.name,
                param_data: JSON.stringify(data),
                type_id: addGoodsData.type_id,
                description: addGoodsData.description,
                price: addGoodsData.price,
                notsell: addGoodsData.notsell,
            }
            proxy.$api.addGood(GoodData)
                .then(res => {
                    if (res.affectedRows > 0) {
                        ElNotification({
                            title: '添加成功',
                            type: 'success'
                        })
                        router.go(0)
                    } else {
                        ElNotification({
                            title: '添加失败，数据存入数据库失败',
                            type: 'error'
                        })
                    }
                })
        } else {
            ElNotification({
                title: '提交失败，请完善商品信息',
                type: 'error'
            })
        }
    })
}

// --删除商品--
const deleteGood = (id) => {
    ElMessageBox.confirm(
        '是否删除该商品？',
        '提示',
        {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
        }
    ).then(() => {
        let params = [id]
        proxy.$api.deleteGoodById(params)
            .then(res => {
                if (res.affectedRows > 0) {
                    ElNotification({
                        title: '删除成功',
                        type: 'success'
                    })
                    router.go(0)
                } else {
                    ElNotification({
                        title: '删除失败，数据库操作失败',
                        type: 'error'
                    })
                }
            })
    }).catch(() => { })
}

// --商品图片上传--
const imgUploadHeaders = { 'Authorization': 'Bearer' + ' ' + Cookies.get('token') } // 图片上传JWT认证
const upload = ref()
const uploadImageUrl = computed(() => {
    return proxy.$api.baseURL + '/goods/uploadGoodImage/' + currentGood.id
})
const handleExceed = (files) => { // 文件超出的回调
    upload.value.clearFiles()
    const file = files[0]
    upload.value.handleStart(file)
}
const submitGoodImage = () => { // 图片文件上传
    upload.value.submit()
}
const deleteGoodImage = () => { // 图片文件删除
    ElMessageBox.confirm(
        '是否删除该商品图片？',
        '提示',
        {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
        }
    ).then(() => {
        proxy.$api.deleteGoodImage([currentGood.id])
            .then(res => {
                if (res.code != -1) {
                    ElNotification({
                        title: '删除成功',
                        type: 'success'
                    })
                    router.go(0)
                } else {
                    ElNotification({
                        title: '删除失败',
                        type: 'error'
                    })
                }
            })
    }).catch(() => { })
}
const imgUploadError = () => { // 上传失败提示
    ElNotification({
        title: '上传失败',
        type: 'error'
    })
}
const imgUploadSuccess = () => { // 上传成功提示
    ElNotification({
        title: '上传成功',
        type: 'success'
    })
    router.go(0)
}
</script>

<style lang="scss" scoped>
#GoodListPage {
    padding: 20px 0;
}
#topBar {
    width: 80%;
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 2rem;
}

span,
#topBarSell,
#topBarPrice {
    margin-right: 1rem;
    font-size: 2rem;
    font-weight: 400;
}

#addGoods {
    margin: 0 auto;
    display: block;
    margin-top: 2rem;
    width: 50%;
    height: 5rem;
    font-size: 3rem;
}

h3 {
    font-size: 2rem;
}

.tag {
    background-color: #fff;
    color: $color_main;
    border-color: $color_assistant;
}

.paramsInput {
    margin-bottom: 1rem;
}

.tagInput {
    max-width: 30%;
}

.paramsBar {
    margin: .5rem 0;
    width: 80%;
}

.paramsTag {
    cursor: pointer;
}

.el-table {

    // 表格中的el-image 在最顶层
    & ::v-deep th.el-table__cell,
    ::v-deep td.el-table__cell {
        // 设置position 使得 子元素不与其产生新的层叠关系
        position: static;
    }
}
</style>
<style scoped>
/deep/.el-tag .el-tag__close {
    color: black;
}

.el-button+.el-button {
    margin-left: 1rem;
}

/deep/.editImage .el-form-item__content {
    flex-direction: column
}

.el-image {
    display: block;
    margin: 0 auto;
}

::v-deep .el-table--scrollable-y .el-table__body-wrapper {
    overflow-y: hidden;
}

/deep/#param-form-item .el-form-item__content {
    display: block;
}
</style>